<?php

class AcctVoucherHTable extends Doctrine_Table
{

    public function saveVoucher(AcctVoucherH $voucher_h, $voucher_d)
    {

        $current_acct_year = Doctrine::getTable("AcctYear")->getCurrentAcctYear(Doctrine::getTable("AcctSet")->getCurrentset());

        //序列号取得方式：先保存voucher_h,取当月voucher_d记录笔数+1，update voucher_d

        $this->getConnection()->beginTransaction();
        //Doctrine::getConnectionByTableName($tableName)
        //Doctrine_Connection::beginTransaction();
        //$this->getConnection()->setAttribute($attribute, $value);

        //echo $voucher_h->getAcctSetId();
        //echo "voucher_sn";
        //取序号
        try
        {
            //$voucher_sn = $this->getMaxVoucherSn($current_acct_year->getAcctYear(), substr($voucher_h->getDate(), 5,2) );
            $voucher_sn = $this->getMaxVoucherSn($current_acct_year->getAcctYear(), $voucher_h->getAcctMon() );
            //print_r($voucher_sn);
            //echo "max_sn = ". $voucher_sn."\r\n";
            //echo "save voucher_h";
            $voucher_h->setVoucherSn(++$voucher_sn);
            $voucher_h->save();

            //save voucher_d
            foreach($voucher_d as $vd)
            {
                $vd->setVoucherhId($voucher_h->getId());
                $vd->save();
            }

        }
        catch (Doctrine_Exception $e)
        {
            $this->getConnection()->rollback();
            throw $e;
            //return false;
        }

        //commit the transaction
        $this->getConnection()->commit();
        return true;

    }

    public function getVoucherQuery(Doctrine_Query $q = null)
    {
        if(is_null($q))
        {
            //$q = $this->createQuery();
            $q = Doctrine_Query::create()
                    ->from("AcctVoucherH v");
        }

        $q->addWhere("acct_set_id = ?", sfContext::getInstance()->getUser()->getAttribute("acct_set"))
                ->addOrderBy("id DESC");

        $q->leftJoin("v.RltOpr opr");
        //$q->leftJoin("v.RltCancelOpr cancel_opr");

        return $q;
    }

    //get the serial no of the vouchers
    private function getMaxVoucherSn($year, $mon)
    {

        //$q = Doctrine_Query::create()->select("max(voucher_sn) as max_sn")
        //        ->from("AcctVoucherH")
        $q = $this->createQuery()
                ->select("max(voucher_sn) as max_sn")
                //->andWhere("acct_set_id = ?", sfConfig::get("app_current_set_id"))
                ->andWhere("acct_set_id = ?", sfContext::getInstance()->getUser()->getAttribute("acct_set"))
                ->andWhere("acct_year = ?", $year)
                //->andWhere("date like ?", $current_acct_year."-".date('m')."%");
                ->andWhere("acct_mon = ?", $mon);
        //echo $q;
        return $q->fetchOne()->max_sn;
    }

    public function getVoucherById($voucher_id)
    {

        $q = $this->createQuery()->addWhere("id = ? ", $voucher_id);

        return $q->fetchOne();
    }


    //accounting posting
    public function Posting( AcctVoucherH $voucher_h)
    {
        
        $this->getConnection()->beginTransaction();

        //取voucher_d
        $voucher_d = $voucher_h->getAcctVoucherD();
        try{

            foreach($voucher_d as $vd) {

                //过账到明细账
                $sl = new AcctSubsidiaryLedger();
                $sl->setAcctSetId($vd->getAcctSetId());
                $sl->setAcctSubjectId($vd->getAcctSubjectId());
                $sl->setAcctYear($voucher_h->getAcctYear()->getAcctYear());
                $sl->setAcctMon($voucher_h->getAcctMon());
                $sl->setVoucherSn($voucher_h->getVoucherSn());
                $sl->setDate($voucher_h->getDate());
                $sl->setDocSummary($vd->getDocSummary());
                $sl->setAmount($vd->getAmount());
                $sl->setDebitCredit($vd->getDebitCredit());
                $sl->setPostOpr(sfContext::getInstance()->getUser()->getAttribute("user_id"));
                //echo $vd->getAmount();
                $sl->save();

                //过账到总账
                //check if the subject id is exists by year, month, subject_id, acct_set_id
                $gls = Doctrine::getTable("AcctGeneralLedger")->getGeneralLedgerByOption(array(
                                "acct_subject_id" => $vd->getAcctSubjectId(),
                                "acct_year" => $voucher_h->getAcctYear()->getAcctYear(),
                                "acct_mon" => $voucher_h->getAcctMon()
                ));
                
                if($gls->count()) {
                    $gl = $gls->getFirst();
                    if( $vd->getDebitCredit() == 'c' ) {
                        $gl->setCreditAmount($gl->getCreditAmount() + $vd->getAmount());
                    } elseif ($vd->getDebitCredit() == 'd') {
                        $gl->setDebitAmount($gl->getDebitAmount() + $vd->getAmount());
                    }
                } else {
                    $gl = new AcctGeneralLedger();
                    $gl->setAcctSetId($vd->getAcctSetId());
                    $gl->setAcctSubjectId($vd->getAcctSubjectId());
                    $gl->setAcctYear($voucher_h->getAcctYear()->getAcctYear());
                    $gl->setAcctMon($voucher_h->getAcctMon());
                    
                    if( $vd->getDebitCredit() == 'c' ) {
                        $gl->setCreditAmount($gl->getCreditAmount() + $vd->getAmount());
                    } elseif ($vd->getDebitCredit() == 'd') {
                        $gl->setDebitAmount($gl->getDebitAmount() + $vd->getAmount());
                    }

                }
                $gl->save();


                //set the voucher_h status
                $voucher_h->setPostOpr(sfContext::getInstance()->getUser()->getAttribute("user_id"));
                $voucher_h->setPostDate(date("Y-m-d"));
                $voucher_h->setIsPosted('1');
                $voucher_h->save();

            }

        } catch ( Doctrine_Exception $e ) {
            $this->getConnection()->rollback();
            throw $e;
        }

        $this->getConnection()->commit();
        return true;
    }

}